package com.waitingsnow.modules.shell.view.video
{
import com.waitingsnow.core.debug.Logger;
import com.waitingsnow.core.model.config.AppConfig;
import com.waitingsnow.core.service.NetConnectionService;
import com.waitingsnow.core.util.ds.ExternalUtil;
import com.waitingsnow.modules.shell.view.video.events.PlayVideoEvent;

import flash.events.Event;
import flash.events.NetStatusEvent;
import flash.events.TimerEvent;
import flash.media.SoundTransform;
import flash.media.Video;
import flash.net.NetStream;
import flash.utils.Timer;
import flash.utils.clearInterval;
import flash.utils.setInterval;
import flash.utils.setTimeout;

/**
 * 
 * @author waitingsnow
 * $Id: PlayVideo.as 2 2012-05-17 10:10:03Z cgslendy@gmail.com $
 */
public class PlayVideo extends Video
{
	//==========================================================================
	//  Constructor
	//==========================================================================
	/**
	 * Constructs a new <code>PlayVideo</code> instance.
	 * 
	 */
	public function PlayVideo(width:int=320, height:int=240)
	{
		super(width, height);
		smoothing = true;
		deblocking = 2;
	}
	
	//==========================================================================
	//  Variables
	//==========================================================================
	private var connService:NetConnectionService;
	private var playNs:NetStream;
	private var reConnectIntervalID:int;
	private var replayIntervalID:int;
	private var _streamName:String;
	private var countTime:Timer;
	private var bufferCount:int;
	private var playFlag:Boolean = true;
	
	//==========================================================================
	//  Methods
	//==========================================================================
	public function startPlay(streamName:String):void
	{
		_streamName = streamName;
		if (connService && connService.connected)
		{
			initNetstream();
		}
		else
		{
			initConn();
		}
	}
	
	public function dispose():void
	{
		parent && parent.removeChild(this);
		playNs && playNs.close();
		connService && connService.dispose();
	}
	
	public function setSize(width:int, height:int):void
	{
		this.width = width;
		this.height = height;
	}
	
	public function resize():void
	{
		
	}
	
	private function initConn():void
	{
		if (!connService)
		{
			connService = new NetConnectionService();
			connService.addEventListener(Event.CONNECT, connectHandler);
			connService.addEventListener(Event.CLOSE, connCloseHandler);
		}
		connService.startConn(AppConfig.VIDEO_ACCEPT_URL, AppConfig.VIDEO_CONN_TOKEN);
	}
	
	private function initNetstream():void
	{
		removeNs();
		playNs = new NetStream(connService.connection);
		playNs.client = {}; 
		playNs.addEventListener(NetStatusEvent.NET_STATUS, playNetStatusHandler);
		playNs.bufferTime = 2;
		playFlag && playNs.play(_streamName);
		Logger.log("正在播放流: " + _streamName);
		attachNetStream(playNs);
	}
	
	private function removeNs():void
	{
		if (playNs)
		{
			playNs.removeEventListener(NetStatusEvent.NET_STATUS, playNetStatusHandler);
			playNs.close();
		}
	}
	
	private function replay():void
	{
		Logger.log("replay");
		connService.connected && playFlag && playNs && playNs.play(_streamName);
	}
	
	public function pause():void
	{
		Logger.log("pause");
		playFlag = false;
		playNs && playNs.close();
	}
	
	public function resume():void
	{
		Logger.log("resume");
		playFlag = true;
		playNs && playNs.play(_streamName);
	}
	
	public function startBeginAD():void
	{
		this.visible = false;
		playNs.soundTransform = new SoundTransform(0);
		/*attachNetStream(null);*/
	}
	
	public function stopBeginAD():void
	{
		this.visible = true;
		playNs.soundTransform = new SoundTransform(1);
		/*playNs && attachNetStream(playNs);*/
	}
	
	//==========================================================================
	//  Event Handlers
	//==========================================================================
	private function connectHandler(event:Event):void
	{
		clearInterval(reConnectIntervalID);
		initNetstream();
	}
	
	private function connCloseHandler(event:Event):void
	{
		Logger.log("开始断线重连...");
		reConnectIntervalID = setTimeout(initConn, 1000);
	}
	
	private function playNetStatusHandler(event:NetStatusEvent):void
	{
		var result:String = event.info.code;
		Logger.log("play netStream status: " + result);
		if (result == "NetStream.Play.UnpublishNotify")
		{
			clearInterval(replayIntervalID);
			/*TweenLite.to(this, 1, {alpha:0});*/
			replayIntervalID = setInterval(replay, 1000);
			dispatchEvent(new PlayVideoEvent(PlayVideoEvent.UN_PUBLISH_NOTIFY, true));
		}
		else if (result == "NetStream.Play.Start")
		{
			/*TweenLite.to(this, 1, {alpha:1});*/
			clearInterval(replayIntervalID);
			if (!countTime)
			{
				countTime = new Timer(1000*60);
				countTime.addEventListener(TimerEvent.TIMER, countTimeHandler);
				countTime.start();
			}
		}
		else if (result == "NetStream.Buffer.Full")
		{
			dispatchEvent(new PlayVideoEvent(PlayVideoEvent.PLAY_AD_BEGIN));
			dispatchEvent(new PlayVideoEvent(PlayVideoEvent.PLAY_START, true));
		}
		else if (result == "NetStream.Buffer.Empty")
		{
			bufferCount ++;
		}
	}
	
	private function countTimeHandler(event:TimerEvent):void
	{
		ExternalUtil.call(AppConfig.VIDEO_STREAM_BUFFER_TO_JS, bufferCount, 0);
		bufferCount = 0;
	}
}
}